package com.zy.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.zy.fallback.SentinelFallback;
import com.zy.feign.ProductFeign;
import com.zy.util.Result;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @author xyz
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/sentinel")
public class SentinelController {

    @SentinelResource(value = "execute", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @GetMapping("/execute")
    public Result execute() {
        log.info("请求：测试..");
        return Result.ok();
    }

    @SentinelResource(value = "execute2", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @RequestMapping("execute2")
    public Result execute2() {
        log.info("接收到请求：调用execute2()");
        return Result.ok();
    }

    @SneakyThrows
    @SentinelResource(value = "rt", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @RequestMapping("rt")
    public Result rt() {
        TimeUnit.SECONDS.sleep(1L);
        return Result.ok("rt调用成功");
    }

    private int i = 0;
    @SentinelResource(value = "ex", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @RequestMapping("ex")
    public Result ex() {
        if(++i % 3 ==0){
            throw new RuntimeException("爆发异常");
        }
        return Result.ok("ex调用成功");
    }

    private int exCountNum = 0;

    @SentinelResource(value = "ex-count", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @RequestMapping("ex-count")
    public Result exCount() {
        if (++exCountNum % 3 == 0) {
            throw new RuntimeException("资源ex-count人为异常");
        }
        return Result.ok("资源ex-count调用成功");
    }

    @SentinelResource(value = "white-auth", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @RequestMapping("white-auth")
    public Result whiteAuth() {
        log.info("资源white-auth调用成功");
        return Result.ok("资源white-auth调用成功");
    }

    @SentinelResource(value = "black-auth", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @RequestMapping("black-auth")
    public Result blackAuth() {
        log.info("资源black-auth调用成功");
        return Result.ok("资源black-auth调用成功");
    }

    @SentinelResource(value = "param", fallbackClass = SentinelFallback.class, fallback = "fallback")
    @RequestMapping("param")
    public Result param(@RequestParam(required = false) String name,
                        @RequestParam(required = false) Integer age) {
        log.info("资源param调用成功");
        return Result.ok("资源param调用成功");
    }

    @Autowired
    @Qualifier("productFeign")
    private ProductFeign productFeign;

    @SentinelResource(value = "open-feign")
    @RequestMapping("open-feign")
    public Result openFeign(@RequestParam("product-id") Integer productId) {
        log.info("接收到参数: {}", productId);
        return productFeign.selectById(productId);
    }
}
